                   package org.benjamin.lending.controller;


import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.validation.Valid;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.benjamin.lending.domain.entity.MemberInfo;
import org.benjamin.lending.domain.entity.MemberStatus;
import org.benjamin.lending.domain.form.RealNameForm;
import org.benjamin.lending.domain.form.RechargeForm;
import org.benjamin.lending.domain.form.WithdrawForm;
import org.benjamin.lending.domain.transact.BasicOutBean;
import org.benjamin.lending.domain.transact.TransactBean;
import org.benjamin.lending.service.MemberInfoService;
import org.benjamin.lending.service.QueueService;
import org.benjamin.lending.service.TransactService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.fasterxml.jackson.databind.ObjectMapper;

@Controller
@RequestMapping(value = "user")
public class UserController {

	private Logger logger = LogManager.getLogger();
	
	private Object mockRest;

	@Autowired
	private TransactService transactService;
	
	@Autowired
	private CacheManager cacheManager;

	@Autowired
	private MemberInfoService memberInfoService;

	@Autowired
	private QueueService queueService;

	@RequestMapping(value = "index")
	public ModelAndView index() {
		ModelAndView modelAndView = new ModelAndView("user/index");
		UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		MemberInfo memberInfo = this.memberInfoService.findMemberDetails(userDetails.getUsername());
		MemberStatus memberStatus = this.memberInfoService.findMemberStatusObject(userDetails.getUsername());
		modelAndView.addObject("memberInfo",memberInfo);
		modelAndView.addObject("memberStatus",memberStatus);
		return modelAndView;
	}

	@GetMapping(value = "recharge")
	public ModelAndView recharge() {
		ModelAndView modelAndView = new ModelAndView("user.recharge");
		logger.debug("访问用户充值页面");
		modelAndView.addObject("rechargeForm",new RechargeForm());
		return modelAndView;
	}

	@PostMapping(value = "recharge")
	public ModelAndView doRecharge(@Valid @ModelAttribute("rechargeForm") RechargeForm rechargeForm,
			BindingResult bindingResult) {
		ModelAndView modelAndView = new ModelAndView("user.recharge");
		logger.debug("提交充值表单");
		if (bindingResult.hasErrors()) {
			logger.debug("充值表单参数检查到有错误，请检查,{}", bindingResult.getErrorCount());
			return modelAndView;
		}
		logger.debug("Spring Security获取当前用户名");
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		String username;
		if (principal instanceof UserDetails) {
			UserDetails userDetails = (UserDetails) principal;
			username = userDetails.getUsername();
			logger.debug("UserDetails username:{} password:{}", userDetails.getUsername(), userDetails.getPassword());
		} else {
			username = principal.toString();
			logger.debug("Not UserDetails");
		}

		BasicOutBean basicOutBean = this.transactService.userRechargeRequest(rechargeForm, username);
		Cache cache = this.cacheManager.getCache("org.lending");
		cache.put(basicOutBean.getTransactBean().getId(), basicOutBean.getTransactBean());
		logger.info("完成数据封装");
		modelAndView.setView(new RedirectView("/transact/request/"+basicOutBean.getTransactBean().getParamterMap().get("requestId").toString(),true));
		return modelAndView;
	}

	@GetMapping(value = "withdraw")
	public ModelAndView withdraw() {
		ModelAndView modelAndView = new ModelAndView("user.withdraw");
		return modelAndView;
	}
	
	/**
	 * 提现操作
	 * @return
	 */
	@PostMapping(value = "withdraw")
	public ModelAndView doWithdraw(@Valid WithdrawForm withdrawForm,BindingResult bindingResult) {
		logger.info("提现操作");
		ModelAndView modelAndView = new ModelAndView();
		UserDetails userDetails = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		BasicOutBean basicOutBean = this.transactService.withdrawRequest(userDetails.getUsername(),withdrawForm,BigDecimal.ZERO);
		TransactBean transactBean = basicOutBean.getTransactBean();
		modelAndView.addObject("transactBean",transactBean);
		modelAndView.setView(new RedirectView("/transact/request/"+transactBean.getId(),true));
		return modelAndView;
	}
	
	/**
	 * 开通账户，
	 * 在开通账户之前，先把用户实名认证
	 * @return
	 */
	@GetMapping(value = "openAccount")
	public ModelAndView openAccess() {
		ModelAndView modelAndView = new ModelAndView();
		RedirectView redirectView = new RedirectView();
		UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		if(!this.memberInfoService.checkRealName(userDetails.getUsername())) {
			redirectView.setUrl("/user/realName");
			redirectView.setContextRelative(true);
			logger.info("重定向用户实名认证");
		}else {
			BasicOutBean basicOutBean = this.transactService.registerAccessRequest(userDetails.getUsername());	
			redirectView.setUrl("/transact/request/"+basicOutBean.getTransactBean().getId());
			redirectView.setContextRelative(true);
			logger.info("实名认证已经通过，直接开通账户");
		}
		modelAndView.setView(redirectView);
		return modelAndView;
	}
	
	@GetMapping(value = "realName")
	public ModelAndView realName() {
		ModelAndView modelAndView = new ModelAndView("user/realName");
		UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		MemberStatus memberStatus = this.memberInfoService.findMemberStatusObject(userDetails.getUsername());
		modelAndView.addObject("memberStatus",memberStatus);
		return modelAndView;
	}
	
	@ResponseBody
	@PostMapping("realName")
	public Map<String,Object> realName(@Valid RealNameForm realNameForm,BindingResult bindingResult){
		Map<String,Object> resultMap = new HashMap<String,Object>();
		try {
			if(bindingResult.hasErrors()) {
				resultMap.put("status", 300);
				resultMap.put("message", "提交参数有错误");
				return resultMap;
			}
			logger.info("接受用户的实名认证操作：提交参数{}",realNameForm.toString());
			UserDetails userDetails = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			BasicOutBean basicOutBean = this.transactService.realNameRequest(userDetails.getUsername(),realNameForm);
			this.queueService.execute();
			resultMap.put("status",200);
			resultMap.put("message", "您的申请已经受理，正在审核中！");
		}catch(Exception e) {
			logger.error(e.getMessage(),e);
			resultMap.put("status", 300);
			resultMap.put("message", e.getMessage());
		}
		return resultMap;
	}
	
	@RequestMapping(value = "securityCenter")
	public ModelAndView securityCenter() {
		ModelAndView modelAndView = new ModelAndView("user/securityCenter");
		return modelAndView;
	}

}
